package com.purchase.ml.service.order.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.purchase.ml.bean.base.ApiRestResult;
import com.purchase.ml.bean.req.mail.MailMessage;
import com.purchase.ml.bean.req.order.*;
import com.purchase.ml.bean.req.shoppingcart.ProductCartReq;
import com.purchase.ml.bean.res.dashboard.OrderRecentQueryRes;
import com.purchase.ml.bean.res.order.OrderInvoiceQueryInfoRes;
import com.purchase.ml.bean.res.order.OrderInvoiceQueryRes;
import com.purchase.ml.bean.res.order.OrderQueryInfoRes;
import com.purchase.ml.bean.res.order.OrderQueryRes;
import com.purchase.ml.bean.sdk.IpayNewDto;
import com.purchase.ml.bean.vo.dealer.SysDealerBriefVo;
import com.purchase.ml.bean.vo.order.OrderRedisVo;
import com.purchase.ml.consts.CommonConsts;
import com.purchase.ml.consts.Constants;
import com.purchase.ml.consts.MailConstants;
import com.purchase.ml.entity.acc.SysUser;
import com.purchase.ml.entity.dealer.SysAddr;
import com.purchase.ml.entity.dealer.SysDealer;
import com.purchase.ml.entity.dealer.SysDealerPruduct;
import com.purchase.ml.entity.order.*;
import com.purchase.ml.entity.prod.SysProduct;
import com.purchase.ml.entity.prod.SysProductSku;
import com.purchase.ml.enums.OrderStatusEnum;
import com.purchase.ml.enums.RetStatusNum;
import com.purchase.ml.enums.SysSeqNameEnum;
import com.purchase.ml.exception.BizException;
import com.purchase.ml.mapper.dealer.DealerProductMapper;
import com.purchase.ml.mapper.dealer.SysAddrMapper;
import com.purchase.ml.mapper.dealer.SysDealerMapper;
import com.purchase.ml.mapper.order.*;
import com.purchase.ml.mapper.prod.SysProdMapper;
import com.purchase.ml.security.JwtUtil;
import com.purchase.ml.service.common.CommonSeqService;
import com.purchase.ml.service.dealer.SysDealerService;
import com.purchase.ml.service.email.order.OrderEmail;
import com.purchase.ml.service.order.SysOrderService;
import com.purchase.ml.service.prod.DealerProductService;
import com.purchase.ml.service.prod.SysProdService;
import com.purchase.ml.service.prod.SysProdSkuService;
import com.purchase.ml.service.sdk.Ipay88Service;
import com.purchase.ml.service.shoppingcart.SysShoppingCartService;
import com.purchase.ml.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;

import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.purchase.ml.consts.CommonConsts.ROLETYPE_DEALER;
import static com.purchase.ml.exception.CommonEnum.ORDER_PAID;
import static com.purchase.ml.exception.CommonEnum.PRODUCT_EXIST_STOCK;

/**
 * Created by kyyang on 2021/2/28 19:32
 */
@Slf4j
@Service
public class SysOrderServiceImpl implements SysOrderService {
    @Autowired
    private CommonSeqService commonSeqService;

    @Autowired
    private SysOrderMapper sysOrderMapper;

    @Autowired
    private SysOrderDetailMapper sysOrderDetailMapper;

    @Autowired
    private SysProdService sysProdService;

    @Autowired
    private SysOrderMsgMapper sysOrderMsgMapper;

    @Autowired
    private SysOrderStateMapper sysOrderStateMapper;

    @Autowired
    private SysDealerMapper sysDealerMapper;

    @Autowired
    private SysAddrMapper sysAddrMapper;

    @Autowired
    private SysDealerCollectMapper sysDealerCollectMapper;
    @Autowired
    private SysShoppingCartService sysShoppingCartService;
    @Autowired
    private DealerProductService dealerProductService;
    @Autowired
    private SysProdSkuService sysProdSkuService;
    @Autowired
    private SysPayInfoMapper sysPayInfoMapper;
    @Autowired
    private DealerProductMapper dealerProductMapper;
    @Autowired
    private SysProdMapper sysProdMapper;

    @Autowired
    private SysDealerService sysDealerService;

    @Autowired
    private OrderEmail orderEmail;

    @Override
    @Transactional
    public ApiRestResult orderCreate(OrderAddReq orderAddReq) throws NoSuchAlgorithmException {

        SysUser currentUser = JwtUtil.getCurrentUser();
        SysDealer sysDealer = sysDealerMapper.selectByDealerId(currentUser.getDealerId());
        //正常状态并且已经支付商户费用
        if( sysDealer.getState()!=1 || sysDealer.getIsPaid() != 1 ){
            return ApiRestResult.err(RetStatusNum.NO_CREATE_ORDER.getMessage(),RetStatusNum.NO_CREATE_ORDER.getCode());
        }

        //TODO 库存校验  库存更改   价格改变问题

        List<ProductCartReq> detail = orderAddReq.getDetail();
        //避免修改购物车不成功；直接下单;超出库存数量；
        for(ProductCartReq productDetail : detail){
            SysProductSku sysProductSku = sysProdSkuService.findProductSkuByProductId(productDetail.getProductId());
            if(Integer.valueOf(ROLETYPE_DEALER).equals(currentUser.getRoleType())){
                SysDealer currentDealer = sysDealerService.findByDealerId(currentUser.getDealerId());
                SysDealerPruduct sysDealerPruduct = dealerProductMapper.findBuyerProductByDealerId(currentDealer.getSuperior(), productDetail.getProductId());
                BeanUtils.copyProperties(sysDealerPruduct,sysProductSku);
            }
            if(sysProductSku==null||sysProductSku.getStock() < productDetail.getQuantity()){
                return ApiRestResult.err(RetStatusNum.UNDERSTOCK.getMessage(), RetStatusNum.UNDERSTOCK.getCode());
            }
            if(sysProductSku.getMoq() > productDetail.getQuantity()){
                return ApiRestResult.err(RetStatusNum.LESS_MOQ.getMessage(), RetStatusNum.LESS_MOQ.getCode());
            }
        }
        SysOrderMsg orderMsg = orderAddReq.getOrderMsg();

        //获取订单号
        Long oid = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_ORDER.getCode());
//        Long oid = commonSeqService.curSysOrderSeqAnd2Random(SysSeqNameEnum.SEQ_ORDER.getCode()); //2位随机数

        //商品总额
        BigDecimal totalM = BigDecimal.ZERO;

        //一级利润
        BigDecimal profitsFirSt = BigDecimal.ZERO;
        //二级利润
        BigDecimal profitsSecond = BigDecimal.ZERO;
        Date curDate = new Date();
        //创建订单明细
        for(ProductCartReq p : detail){
            if(p.getQuantity()<=0){
                continue;
            }
            SysProduct product = sysProdService.findProductByProductId(p.getProductId());
            SysOrderDetail sysOrderDetail = new SysOrderDetail();
            sysOrderDetail.setOid(oid);
            sysOrderDetail.setProductId(p.getProductId());
            sysOrderDetail.setQuantity(p.getQuantity());
            //根据商户类型不同；计算应售卖的价格；主景经销商购买
            BigDecimal productTotalMoney = ShoppingCartUtils.getProductTotalMoney(product, p.getQuantity(),currentUser.getRoleType());
            //如果是主经销商；价格需要×度量单位
            SysProductSku sku = sysProdSkuService.findProductSkuByProductId(p.getProductId());
            if(currentUser.getRoleType() == CommonConsts.ROLETYPE_MASTER ){
                productTotalMoney = new BigDecimal(sku.getExchangeNum()).multiply(productTotalMoney); //价格*兑换数量；
                sysOrderDetail.setPrice(product.getPriceMasterDealer());
                sysOrderDetail.setBuyunit(sku.getUnit());
            }else{
                sysOrderDetail.setPrice(product.getPriceDealer());
                sysOrderDetail.setBuyunit(sku.getMasterUnit()); //masterUnit 实际上是主经销商出售的单位；经销商购买单位
            }
            BigDecimal moneyNumproductTotalMoney = new BigDecimal(NumberUtils.getRoundByPenny(productTotalMoney));
            sysOrderDetail.setAllmoney(moneyNumproductTotalMoney);
            totalM = totalM.add(productTotalMoney);

            //如果是主经销商购买：主经销商购买只算一级利润；经销商只算二级
            if(currentUser.getRoleType().equals(CommonConsts.ROLETYPE_MASTER)){
                BigDecimal profit = (product.getPriceMasterDealer().subtract(product.getPriceCost())).multiply(BigDecimal.valueOf(p.getQuantity()));
                profitsFirSt = profitsFirSt.add(profit.multiply(BigDecimal.valueOf(sku.getExchangeNum())));
            }else if (currentUser.getRoleType().equals(CommonConsts.ROLETYPE_DEALER)){
                BigDecimal tempProfit2 = product.getPriceMasterDealer();
                BigDecimal profitSec = (product.getPriceDealer().subtract(tempProfit2)).multiply(BigDecimal.valueOf(p.getQuantity()));
                profitsSecond = profitsSecond.add(profitSec);
            }
            // 如果是主经销商买：计算一级利润 ；采用住经销商价格
            //设置单价
            sysOrderDetailMapper.insert(sysOrderDetail);
        }
        //创建订单留言
        orderMsg.setOid(oid);
        sysOrderMsgMapper.insert(orderMsg);
        //创建订单表记录
        SysOrder sysOrder = new SysOrder();
        sysOrder.setOid(oid);
        if(sysDealer.getNeedPay() == CommonConsts.NEED_PAY){
            sysOrder.setPayId(oid);
        }
        sysOrder.setBuyer(currentUser.getDealerId());
        BigDecimal moneyNumFirSt = new BigDecimal(NumberUtils.getRoundByPenny(profitsFirSt));
        BigDecimal moneyNumSecond = new BigDecimal(NumberUtils.getRoundByPenny(profitsSecond));
        sysOrder.setFirstLevelProfit(moneyNumFirSt);
        sysOrder.setSecondLevelProfit(moneyNumSecond);
        //发票号 ：随机码加单号
        sysOrder.setInvoiceId(StringUtils.generateCode(2) + oid);
        sysOrder.setPayMethod("Ipay88");
        BigDecimal moneyNumTotalM = new BigDecimal(NumberUtils.getRoundByPenny(totalM));
        sysOrder.setPuductFee(moneyNumTotalM);
        sysOrder.setSubFee(moneyNumTotalM);
        sysOrder.setCreatedAt(curDate);
        sysOrder.setUpdateAt(curDate);
        sysOrder.setState(0); //设置为待付款
        sysOrder.setDeliveryFee(BigDecimal.ZERO);
        sysOrder.setAdaptFee(BigDecimal.ZERO);
        //设置卖家
        sysOrder.setSellers(sysDealer.getSuperior());
        sysOrder.setDealerType(sysDealer.getDealerType());
        int insert = sysOrderMapper.insert(sysOrder);
        if(insert > 0){
            //创建订单状态记录
            SysOrderState sysOrderState = new SysOrderState();
            sysOrderState.setOid(oid);
            sysOrderState.setState(0);
            sysOrderState.setStateChageAt(curDate);
            int insertNum = sysOrderStateMapper.insert(sysOrderState);
            if( insertNum > 0) {
                sysShoppingCartService.clearCart();
            }

            //判断类型发送邮件
            if(currentUser.getRoleType() == CommonConsts.ROLETYPE_MASTER){
                //主经销商下单发送邮件 sysOrder
                MailMessage sendMdealerPurMsg = orderEmail.getSendMdealerPurMsg(sysOrder);
                String message2Owner = JSON.toJSONString(sendMdealerPurMsg);
                RedisClient.lpush(MailConstants.REDIS_MAIL_MESSAGE,message2Owner);
                MailMessage mdealerPurConfirmMsg = orderEmail.getMdealerPurConfirmMsg(sysOrder);
                String message2Mdealer = JSON.toJSONString(mdealerPurConfirmMsg);
                RedisClient.lpush(MailConstants.REDIS_MAIL_MESSAGE,message2Mdealer);
            }else{
                //经销商下单发送邮件
                MailMessage sendDealerPurMsg = orderEmail.getSendDealerPurMsg(sysOrder);
                String message2Mdealer = JSON.toJSONString(sendDealerPurMsg);
                RedisClient.lpush(MailConstants.REDIS_MAIL_MESSAGE,message2Mdealer);
                MailMessage dealerPurConfirmMsg = orderEmail.getDealerPurConfirmMsg(sysOrder);
                String message2Dealer = JSON.toJSONString(dealerPurConfirmMsg);
                RedisClient.lpush(MailConstants.REDIS_MAIL_MESSAGE,message2Dealer);
            }
            //需要支付的经销商：经销商全部；主景经销商部分；
            if(sysDealer.getNeedPay() == CommonConsts.NEED_PAY){
                //创建支付订单
                SysPayinfo sysPayinfo = new SysPayinfo();
                sysPayinfo.setCreateAt(curDate);
                sysPayinfo.setMoney(moneyNumTotalM);
                sysPayinfo.setPayId(oid);
                sysPayinfo.setPayMethod("OrderPay");
                sysPayinfo.setState(OrderStatusEnum.UNPAID.getCode());
                sysPayinfo.setType(Constants.PAY_ORDER_TYPE_ORDER);
                sysPayInfoMapper.insert(sysPayinfo);
                //组织支付数据
                SysUser sysUser = JwtUtil.getCurrentUser();
                IpayNewDto ipayNewDto = new IpayNewDto();
                ipayNewDto.setPayType(Constants.PAY_ORDER_TYPE_ORDER);
                ipayNewDto.setRefNo(oid.toString());
                ipayNewDto.setAmount(moneyNumTotalM);
                ipayNewDto.setProdDesc("Buy Oil Product");
                ipayNewDto.setUserName(sysUser.getName());
                ipayNewDto.setUserEmail(sysUser.getEmail());
                ipayNewDto.setUserContact(sysUser.getTelNumber());
                Map<String,String> payDate = SdkIpay88Utils.doRequestToIpay88(ipayNewDto);
                //返回数据前端表单提交
                return ApiRestResult.ok(payDate);
            }
            return ApiRestResult.ok();
        }else{
            return ApiRestResult.err(RetStatusNum.ORDER_CREAT_FAIL.getMessage(),RetStatusNum.ORDER_CREAT_FAIL.getCode());
        }
    }

    @Override
    public ApiRestResult orderAdminCreate(OrderAdminAddReq req) {
        List<ProductCartReq> detail = req.getDetail();
        SysOrderMsg orderMsg = req.getOrderMsg();

        //获取订单号
//        Long oid = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_ORDER.getCode());
        Long oid = commonSeqService.curSysOrderSeqAnd2Random(SysSeqNameEnum.SEQ_ORDER.getCode());

        //商品总额
        BigDecimal totalM = BigDecimal.ZERO;

        //一级利润
        BigDecimal profitsFirSt = BigDecimal.ZERO;
        //二级利润
        BigDecimal profitsSecond = BigDecimal.ZERO;
        Date curDate = new Date();
        //创建订单明细
        for(ProductCartReq p:detail){
            if(p.getQuantity()<=0){
                continue;
            }
            SysProduct product = sysProdService.findProductByProductId(p.getProductId());
            SysOrderDetail sysOrderDetail = new SysOrderDetail();
            sysOrderDetail.setOid(oid);
            sysOrderDetail.setProductId(p.getProductId());
            sysOrderDetail.setQuantity(p.getQuantity());
            //查询大代理到经销商的换算单位
            SysProductSku sku = sysProdSkuService.findProductSkuByProductId(p.getProductId());
            //管理员都是添加给住经销商；使用之经销商类型

            BigDecimal productTotalMoney = ShoppingCartUtils.getProductTotalMoney(product, p.getQuantity(),CommonConsts.ROLETYPE_MASTER);
            productTotalMoney = new BigDecimal(sku.getExchangeNum()).multiply(productTotalMoney);
            BigDecimal moneyNumProductTotalMoney = new BigDecimal(NumberUtils.getRoundByPenny(productTotalMoney));
            sysOrderDetail.setAllmoney(moneyNumProductTotalMoney);

            totalM = totalM.add(productTotalMoney);
            //涉及到单位不同的；二级利润需要修改计算方式：需要经销商价格是按瓶卖

            BigDecimal firstProfit = (product.getPriceMasterDealer().subtract(product.getPriceCost())).multiply(BigDecimal.valueOf(p.getQuantity()));
            profitsFirSt = profitsFirSt.add(firstProfit.multiply(BigDecimal.valueOf(sku.getExchangeNum())));
            // 设置单价与购买单位
            sysOrderDetail.setPrice(product.getPriceMasterDealer());
            sysOrderDetail.setBuyunit(sku.getUnit());
            sysOrderDetailMapper.insert(sysOrderDetail);
        }
        //创建订单留言
        orderMsg.setOid(oid);
        sysOrderMsgMapper.insert(orderMsg);

        //创建订单表记录
        SysOrder sysOrder = new SysOrder();
        sysOrder.setOid(oid);
        SysDealer sysDealer = sysDealerMapper.selectByDealerId(req.getDealerId());
        if(sysDealer == null){
            return ApiRestResult.err(RetStatusNum.NO_DEALER.getMessage(),RetStatusNum.NO_DEALER.getCode());
        }
        sysOrder.setBuyer(req.getDealerId());   //使用传进来的商户ID
        BigDecimal moneyNumProfitsFirSt = new BigDecimal(NumberUtils.getRoundByPenny(profitsFirSt));
        sysOrder.setFirstLevelProfit(moneyNumProfitsFirSt);
        sysOrder.setSecondLevelProfit(profitsSecond);
        //发票号
        sysOrder.setInvoiceId(StringUtils.generateCode(2)+oid);;  //两位随机符号+单号
        sysOrder.setPayMethod("Ipay88");
        BigDecimal moneyNumTotalM = new BigDecimal(NumberUtils.getRoundByPenny(totalM));
        sysOrder.setPuductFee(moneyNumTotalM);
        sysOrder.setSubFee(moneyNumTotalM);
        sysOrder.setCreatedAt(curDate);
        sysOrder.setState(0); //设置为待付款
        sysOrder.setDeliveryFee(BigDecimal.ZERO);
        sysOrder.setAdaptFee(BigDecimal.ZERO);
        sysOrder.setSellers(sysDealer.getSuperior());
        sysOrder.setDealerType( CommonConsts.ROLETYPE_MASTER);//只能添加到主经销商
        int insert = sysOrderMapper.insert(sysOrder);
        if(insert > 0){
            //创建订单状态记录
            SysOrderState sysOrderState = new SysOrderState();
            sysOrderState.setOid(oid);
            sysOrderState.setState(0);
            sysOrderState.setStateChageAt(curDate);
            int insertNum = sysOrderStateMapper.insert(sysOrderState);
            if( insertNum > 0) {
                sysShoppingCartService.clearCart();
            }
        }else{
            return ApiRestResult.err(RetStatusNum.ORDER_CREAT_FAIL.getMessage(),RetStatusNum.ORDER_CREAT_FAIL.getCode());
        }
        return ApiRestResult.ok();
    }

    @Override
    public com.purchase.ml.bean.page.Page<OrderQueryRes> orderQuery(OrderQueryReq req,Boolean isMyOrder) {
        IPage<SysOrder> page = new Page<>(req.getPageIndex(),req.getPageNum());
        QueryWrapper<SysOrder> queryWrapper = new QueryWrapper();
        queryWrapper.ne("state",OrderStatusEnum.DELETE.getCode());  //排除已删除的订单
        if(req.getOid()!=null){
            queryWrapper.eq("oid",req.getOid());
        }
        if(req.getState()!=null){
            queryWrapper.eq("state",req.getState());
        }
        if(req.getDealerId()!=null){
            queryWrapper.eq("buyer",req.getDealerId());
        }
        if(org.apache.commons.lang3.StringUtils.isNotBlank(req.getDealerName())){
            //查询经销商对应的ID;
            Long dealerId = sysDealerMapper.selectDealerIdByName(req.getDealerName());
            queryWrapper.eq("buyer",dealerId);
        }

        if( req.getDealerType() != null ){
            queryWrapper.eq("dealer_type",req.getDealerType());
        }
        SysUser currentUser = JwtUtil.getCurrentUser();
        //如果是查询自己
        if(isMyOrder){
            queryWrapper.eq("buyer",currentUser.getDealerId());
        }else{
            //如果不是管理员；出售者只能是自己
            if(currentUser.getRoleType() != CommonConsts.ROLETYPE_ADMIN){
                queryWrapper.eq("sellers",currentUser.getDealerId());
            }
        }
        queryWrapper.orderByDesc("id");

        IPage<SysOrder> sysOrderIPage = sysOrderMapper.selectPage(page, queryWrapper);
        List<OrderQueryRes> orderQueryResList = new ArrayList<>();
        //这里后面需要改为单独查询
        for(SysOrder sysOrder:sysOrderIPage.getRecords()){
            //查询对应经销商：有一级缓存
            SysDealer sysDealer = sysDealerMapper.selectByDealerId(sysOrder.getBuyer());
            if(sysDealer == null){
                continue;
            }
            OrderQueryRes orderQueryRes = new OrderQueryRes();
            BeanUtils.copyProperties(sysOrder,orderQueryRes);
            orderQueryRes.setBuyerName(sysDealer.getDealerName());
            orderQueryRes.setBuyerPhoneNumber(sysDealer.getPhoneNumber());
            orderQueryResList.add(orderQueryRes);
        }
        com.purchase.ml.bean.page.Page<OrderQueryRes> res = new com.purchase.ml.bean.page.Page<>(req.getPageIndex(),req.getPageNum());
        res.setTotal(Long.valueOf(sysOrderIPage.getTotal()).intValue());
        res.setRecords(orderQueryResList);
        return res;
    }

    @Override
    public List<OrderRecentQueryRes> orderRecentQuery() {
        //组合查询需要返回的数据
        SysUser sysUser = JwtUtil.getCurrentUser();
        if(sysUser.getRoleType().equals(CommonConsts.ROLETYPE_ADMIN)){
            //如果是管理员；查询全部出售订单
            return sysOrderMapper.selectRecentOrderAdmin();
        }else if(sysUser.getRoleType().equals(CommonConsts.ROLETYPE_DEALER)) {
            //如果是经销商则查询自己购买的;
            return sysOrderMapper.selectRecentBuyOrderDealer(sysUser.getDealerId());
        }else{
            //大代理与主经销商查询自己出售的
            return sysOrderMapper.selectRecentOrderJoinDealer(sysUser.getDealerId());
        }

    }

    @Override
    public com.purchase.ml.bean.page.Page<OrderInvoiceQueryRes> orderInvoiceQuery(OrderInvoiceQueryReq req) {
        IPage<SysOrder> page = new Page<>(req.getPageIndex(),req.getPageNum());
        QueryWrapper<SysOrder> queryWrapper = new QueryWrapper();
        queryWrapper.ne("state",OrderStatusEnum.DELETE.getCode());  //排除已删除的订单
        queryWrapper.ne("state",OrderStatusEnum.UNPAID.getCode());  //排除未支付的订单
//      判断角色ID
        SysUser sysUser = JwtUtil.getCurrentUser();
        if(sysUser.getRoleType() == CommonConsts.ROLETYPE_MASTER  || sysUser.getRoleType() == CommonConsts.ROLETYPE_DEALER ){
            queryWrapper.eq("buyer",sysUser.getDealerId());
        }
        if(req.getOid()!=null){
            queryWrapper.eq("oid",req.getOid());
        }
        if(req.getDealerId()!=null){
            queryWrapper.eq("dealer_id",req.getDealerId());
        }
        if(org.apache.commons.lang3.StringUtils.isNotBlank(req.getDealerName())){
            queryWrapper.like("dealer_name",req.getDealerName());
        }
        if(org.apache.commons.lang3.StringUtils.isNotBlank(req.getInvoiceId())){
            queryWrapper.like("invoice_id",req.getInvoiceId());
        }
        if(org.apache.commons.lang3.StringUtils.isNotBlank(req.getDate())){
            queryWrapper.apply("date_format(created_at,'%Y-%m-%d')={0}",req.getDate());
        }
        queryWrapper.orderByDesc("id");
        IPage<SysOrder> sysOrderIPage = sysOrderMapper.selectPage(page, queryWrapper);
        List<OrderInvoiceQueryRes> orderQueryResList = new ArrayList<>();
        SimpleDateFormat sdf = DateUtils.dayFormat.get();
        for(SysOrder sysOrder:sysOrderIPage.getRecords()){
            OrderInvoiceQueryRes orderInvoiceQueryRes = new OrderInvoiceQueryRes();
            BeanUtils.copyProperties(sysOrder,orderInvoiceQueryRes);
            Date createdAt = sysOrder.getCreatedAt();

            SysDealer sysDealer = sysDealerMapper.selectByDealerId(sysOrder.getBuyer());
            orderInvoiceQueryRes.setBuyerName(sysDealer.getDealerName());
            orderInvoiceQueryRes.setDealerId(sysOrder.getBuyer());
            String format = sdf.format(createdAt);
            orderInvoiceQueryRes.setDate(format);
            orderQueryResList.add(orderInvoiceQueryRes);
        }

        com.purchase.ml.bean.page.Page<OrderInvoiceQueryRes> res = new com.purchase.ml.bean.page.Page<>(req.getPageIndex(),req.getPageNum());
        res.setTotal(Long.valueOf(sysOrderIPage.getTotal()).intValue());
        res.setRecords(orderQueryResList);
        return res;
    }

    @Override
    @Transactional
    public void jobOrderCollect() {
        //查询昨日订单
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = DateUtils.dayFormat.get();
        //每次跑近7天数据
//        for(int i = 1 ;i<=7 ;i++){
            calendar.add(Calendar.DAY_OF_MONTH,-1);
            String yesToday = sdf.format(calendar.getTime());
            orderCollectByDay(yesToday);
//        }

    }

    private void orderCollectByDay(String yesToday) {

        //为确保任务不被重复执行 应先删除 当天汇总数据
        QueryWrapper<SysDealerCollect> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("data_date",yesToday);
        int delete = sysDealerCollectMapper.delete(deleteWrapper);
        log.info("[{}],共计清除 [{}] 条记录",yesToday,delete);
        //首次初始化扫描全表
        List<SysDealerCollect> list = sysDealerCollectMapper.genOrderCollectByFull(yesToday);
        //后续数据量大时 查询增量方案 查询出昨天累计记录  以下为增量方案 采用时 需注释 首次初始化
//        List<SysDealerCollect> list = sysOrderCollectIncremental(yesToday);
        if(list!=null&&list.size()>0){
            for(SysDealerCollect sys:list){
                sys.setCreateAt(new Date());
                sysDealerCollectMapper.insert(sys);
            }
        }
        log.info("汇总[{}]订单总记录数:[{}] 条",yesToday,list==null?0:list.size());
    }

    @Override
    @Transactional
    public ApiRestResult orderEdit(OrderEditReq orderEditReq) {
//        try {
            SysUser currentUser = JwtUtil.getCurrentUser();
            Date date = new Date();
            log.info("当前用户：[{}],修改订单 [{}] 状态值为:[{}]", currentUser.getAcc(), orderEditReq.getOid(), orderEditReq.getState());
            SysOrder sysOrder = new SysOrder();
            sysOrder.setOid(orderEditReq.getOid());
            sysOrder.setState(Integer.valueOf(orderEditReq.getState()));
            sysOrder.setUpdateAt(date);
            if(Integer.valueOf(orderEditReq.getState()) == OrderStatusEnum.DELIVERED.getCode()){
                sysOrder.setDeliveryAt(date);
            }
            if(Integer.valueOf(orderEditReq.getState()) == OrderStatusEnum.REACHED.getCode()){
                sysOrder.setReciveAt(date);
            }

            QueryWrapper<SysOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("oid", orderEditReq.getOid());
            //检验订单；不是管理员只允许编辑订单出售者是自己的订单
            if(currentUser.getRoleType() != CommonConsts.ROLETYPE_ADMIN){
                wrapper.eq("sellers", currentUser.getDealerId());
            }
            //先查询之前的状态；如果从待定变为成功则更改主经销商的库存;需要在更新之前查询；
            SysOrder sysOrder1 = sysOrderMapper.findOrderByOid(orderEditReq.getOid());
            //如果更新状态等于之前的状态 不做改变
            if(sysOrder1.getState().equals(orderEditReq.getState())){
                return ApiRestResult.ok();
            }
            //不允许逆向修改
            if(sysOrder1.getState() != OrderStatusEnum.UNPAID.getCode() && sysOrder1.getState() > Integer.valueOf(orderEditReq.getState()) && Integer.valueOf(orderEditReq.getState())!=OrderStatusEnum.CANCEL.getCode()){
                throw new BizException(RetStatusNum.REVERSE_CHANGE.getCode(),RetStatusNum.REVERSE_CHANGE.getMessage());
            }
            //不跨级更改(未支付之前)；已经支付的可以跨级修改
            if(Integer.valueOf(orderEditReq.getState()) - sysOrder1.getState() > 1 && sysOrder1.getState() < 1 && Integer.valueOf(orderEditReq.getState())!= OrderStatusEnum.CANCEL.getCode()){
                throw new BizException(RetStatusNum.UNSAFE_CHANGE.getCode(),RetStatusNum.UNSAFE_CHANGE.getMessage());
            }
            // 已支付的订单，不允许取消
            if(sysOrder1.getState() > 0 && Integer.valueOf(orderEditReq.getState()) == OrderStatusEnum.CANCEL.getCode()){
                throw new BizException(RetStatusNum.CAN_NOT_CANCEL.getCode(),RetStatusNum.CAN_NOT_CANCEL.getMessage());
            }
            int updateNum = sysOrderMapper.update(sysOrder, wrapper);
            if(updateNum > 0){
                if(sysOrder1.getState().equals(OrderStatusEnum.UNPAID.getCode()) && Integer.valueOf(orderEditReq.getState()).equals(OrderStatusEnum.PAID.getCode())){
                    //变更库存
                    dealerProductService.changeMasterDealerStock(orderEditReq.getOid());
                    // 检查库存，当小于阀值10的时候，邮件通知卖家
                    List<SysOrderDetail> detailList = sysOrderDetailMapper.findDetailByOid(orderEditReq.getOid());
                    SysOrder dbSysOrder = sysOrderMapper.findOrderByOid(orderEditReq.getOid());
                    for (SysOrderDetail detail:detailList) {
                        SysProduct product = sysProdMapper.selectProductByProductId(detail.getProductId());
                        Integer stockNum = 0;
                        if(Integer.valueOf(CommonConsts.ROLETYPE_ADMIN).equals(currentUser.getRoleType()) || Integer.valueOf(CommonConsts.ROLETYPE_AGENCY).equals(currentUser.getRoleType())){
                            SysProductSku sysProductSku = sysProdSkuService.findProductSkuByProductId(detail.getProductId());
                            stockNum = sysProductSku.getStock();
                        }
                        if(Integer.valueOf(CommonConsts.ROLETYPE_MASTER).equals(currentUser.getRoleType())){
                            SysDealerPruduct sysDealerPruduct = dealerProductMapper.findBuyerProductByDealerId(currentUser.getDealerId(), detail.getProductId());
                            if(sysDealerPruduct != null ){
                                stockNum = sysDealerPruduct.getStock();
                            }
                        }
                        if(stockNum <= Constants.STOCK_NOTIFY){
                            MailMessage stockPurMsg = orderEmail.getStockPurMsg(dbSysOrder,stockNum,product.getProductName());
                            String message2Agent = JSON.toJSONString(stockPurMsg);
                            RedisClient.lpush(MailConstants.REDIS_MAIL_MESSAGE,message2Agent);
                        }
                    }
                }
            }

            SysOrderState sysOrderState = new SysOrderState();
            sysOrderState.setState(Integer.valueOf(orderEditReq.getState()));
            sysOrderState.setOid(orderEditReq.getOid());
            sysOrderState.setStateChageAt(date);
            sysOrderStateMapper.insert(sysOrderState);
//        }catch (Exception e){
//            log.info("e============={}",e);
//            throw new BizException(RetStatusNum.NO_STATE.getCode(),RetStatusNum.NO_STATE.getMessage());
//        }
        return ApiRestResult.ok();
    }
    /***
     * 编辑订单的状态
     */
    @Override
    @Transactional
    public int changeOrderState(OrderEditReq orderEditReq){
        Date date = new Date();
        SysOrder sysOrder = new SysOrder();
        sysOrder.setOid(orderEditReq.getOid());
        sysOrder.setState(Integer.valueOf(orderEditReq.getState()));
        sysOrder.setUpdateAt(date);
        QueryWrapper<SysOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("oid", orderEditReq.getOid());
        int updateNum = sysOrderMapper.update(sysOrder, wrapper);
        //更新成功并且订单买家是住经销商
        if(updateNum > 0 ){
            //变更库存
            dealerProductService.changeMasterDealerStock(orderEditReq.getOid());
        }
        return updateNum;
    }
    @Override
    public ApiRestResult orderDel(List<Long> oids) {
        try {
            SysUser currentUser = JwtUtil.getCurrentUser();
            Date date = new Date();
            log.info("当前用户：[{}],删除订单 [{}]", currentUser.getAcc(), oids);
            SysOrder sysOrder = new SysOrder();
            for(Long oid:oids){
                sysOrder.setState(OrderStatusEnum.DELETE.getCode());
                sysOrder.setUpdateAt(date);
                if(currentUser.getRoleType() != CommonConsts.ROLETYPE_ADMIN && currentUser.getRoleType() != CommonConsts.ROLETYPE_AGENCY ){
                    throw new BizException(RetStatusNum.NO_DEL.getCode(),RetStatusNum.NO_DEL.getMessage());
                }
                SysOrder dbSysOrder = sysOrderMapper.findOrderByOid(oid);
                if(dbSysOrder.getState() > 0){
                    throw new BizException(
                            ORDER_PAID.getResultCode(),"【"+ dbSysOrder.getOid() +"】"+ORDER_PAID.getResultMsg());
                }
                sysOrderMapper.updateStateDel(oid);
            }
        }catch (Exception e){
            log.info("Exception============{}",e);
            throw new BizException(RetStatusNum.NO_DEL.getCode(),RetStatusNum.NO_DEL.getMessage());
        }
        return ApiRestResult.ok();
    }

    @Override
    public ApiRestResult orderSetRedisAdd(OrderRedisVo orderRedisVo) {

        if(orderRedisVo!=null&& org.apache.commons.lang3.StringUtils.isNotBlank(orderRedisVo.getOrderNo())&& org.apache.commons.lang3.StringUtils.isNotBlank(orderRedisVo.getOrderType())){
            Jedis jedis = null;
            try {
                jedis = RedisClient.getJedis();
                jedis.zadd(CommonConsts.ORDER_TYPE_REDIS_KEY,1.0,JSON.toJSONString(orderRedisVo));
            }catch (Exception e){
                log.error("订单[{}] ,插入redis失败 , 原因:[{}]",JSON.toJSONString(orderRedisVo),e);
                 throw new BizException(RetStatusNum.REDIS_SET_ADD_ERROR.getCode(),RetStatusNum.REDIS_SET_ADD_ERROR.getMessage());
            }finally {
                if(jedis!=null){
                    jedis.close();
                }
            }
        }else {
            return ApiRestResult.err(RetStatusNum.PARAMS_ERROR.getMessage(),RetStatusNum.PARAMS_ERROR.getCode());
        }
        return ApiRestResult.ok();
    }

    @Override
    public ApiRestResult orderSetRedisDel(OrderRedisVo orderRedisVo) {
        if(orderRedisVo!=null&& org.apache.commons.lang3.StringUtils.isNotBlank(orderRedisVo.getOrderNo())&& org.apache.commons.lang3.StringUtils.isNotBlank(orderRedisVo.getOrderType())){
            Jedis jedis = null;
            try {
                jedis = RedisClient.getJedis();
                jedis.zrem(CommonConsts.ORDER_TYPE_REDIS_KEY,JSON.toJSONString(orderRedisVo));
            }catch (Exception e){
                log.error("订单[{}] ,删除redis失败 , 原因:[{}]",JSON.toJSONString(orderRedisVo),e);
                throw new BizException(RetStatusNum.REDIS_SET_ADD_ERROR.getCode(),RetStatusNum.REDIS_SET_ADD_ERROR.getMessage());
            }finally {
                if(jedis!=null){
                    jedis.close();
                }
            }
        }else {
            return ApiRestResult.err(RetStatusNum.PARAMS_ERROR.getMessage(),RetStatusNum.PARAMS_ERROR.getCode());
        }
        return ApiRestResult.ok();
    }

    @Override
    public List<OrderRedisVo> queryOrderSetRedisBySub(int start,int end) {
        Jedis jedis = null;
        try {
            jedis = RedisClient.getJedis();
            Set<String> zrevrange = jedis.zrevrange(CommonConsts.ORDER_TYPE_REDIS_KEY, start, end);
            if(zrevrange!=null){
                List<OrderRedisVo> collect = zrevrange.stream().map(s -> JSON.parseObject(s, OrderRedisVo.class)).collect(Collectors.toList());
                return collect;
            }
        }catch (Exception e){
            log.error("查询redis异常:[{}]",e);
        }finally {
            if(jedis!=null){
                jedis.close();
            }
        }
        return Collections.emptyList();
    }

    @Override
    public OrderQueryInfoRes orderQueryInfo(OrderQueryInfoReq req, boolean b) {
        QueryWrapper<SysOrder> queryWrapper = new QueryWrapper();
        queryWrapper.ne("state",OrderStatusEnum.DELETE.getCode());  //排除已删除的订单
        queryWrapper.eq("oid",req.getOid());
        SysUser currentUser = JwtUtil.getCurrentUser();
        //如果是查询自己
        if(b){
            queryWrapper.eq("buyer",currentUser.getDealerId());
        }else{
            //如果不是管理员；出售者只能是自己
            if(currentUser.getRoleType() != CommonConsts.ROLETYPE_ADMIN){
                queryWrapper.eq("sellers",currentUser.getDealerId());
            }
        }
        queryWrapper.orderByDesc("id");

        SysOrder sysOrder = sysOrderMapper.selectOne( queryWrapper);

        //这里后面需要改为单独查询
        OrderQueryInfoRes orderQueryRes = new OrderQueryInfoRes();
        BeanUtils.copyProperties(sysOrder,orderQueryRes);

        //查询订单状态
        QueryWrapper<SysOrderState> wrapperState = new QueryWrapper();
        wrapperState.eq("oid",sysOrder.getOid());
        List<SysOrderState> sysOrderDetails = sysOrderStateMapper.selectList(wrapperState);
        log.info("sysOrderDetails======{}",sysOrderDetails);
        orderQueryRes.setStateChangeRecode(sysOrderDetails);

        //查询订单留言
        QueryWrapper<SysOrderMsg> wrapperMsg = new QueryWrapper();
        wrapperMsg.eq("oid",sysOrder.getOid());
        List<SysOrderMsg> sysOrderMsgs = sysOrderMsgMapper.selectList(wrapperMsg);
        if(sysOrderMsgs!=null&&sysOrderMsgs.size()>0){
            orderQueryRes.setSysOrderMsg(sysOrderMsgs.get(0));
        }
        //查询订单明细
//        QueryWrapper<SysOrderDetail> wrapperDetail = new QueryWrapper();
//        wrapperDetail.eq("oid",sysOrder.getOid());
        List<SysOrderDetail> sysOrderDetailList = sysOrderDetailMapper.findDetailAndProductInfoByOid(sysOrder.getOid());
        orderQueryRes.setDetail(sysOrderDetailList);
//        SysDealer sysDealer = sysDealerMapper.selectByDealerId(JwtUtil.getCurrentUser().getDealerId());
        //查询购买者的地址
        SysDealer sysDealer = sysDealerMapper.selectByDealerId(orderQueryRes.getBuyer());
        if(sysDealer != null){
            SysAddr sysAddr = sysAddrMapper.findAddrByAddrId(sysDealer.getBillingAddrId());
            if(sysAddr != null){
                orderQueryRes.setBillesAddres(sysAddr);
            }
            SysAddr sysAddr2 = sysAddrMapper.findAddrByAddrId(sysDealer.getShopAddrId());
            if(sysAddr2 != null){
                orderQueryRes.setShopAddres(sysAddr2);
            }
            orderQueryRes.setDealerName(sysDealer.getDealerName());
        }
        // 查询卖家的购物地址
        SysDealer sysDealer2 = sysDealerMapper.selectByDealerId(orderQueryRes.getSellers());
        if(sysDealer2 != null){
            SysAddr sysAddr3 = sysAddrMapper.findAddrByAddrId(sysDealer2.getShopAddrId());
            SysDealerBriefVo briefVo = new SysDealerBriefVo();
            briefVo.setDealerName(sysDealer2.getDealerName());
            briefVo.setEmailAddress(sysDealer2.getEmailAddress());
            briefVo.setLogoUrl(sysDealer2.getLogoUrl());
            briefVo.setShopAddr(sysAddr3);
            orderQueryRes.setDealerBrief(briefVo);
        }
        return orderQueryRes;
    }

    @Override
    public OrderInvoiceQueryInfoRes orderInvoiceQueryInfo(OrderInvoiceQueryInfoReq req) {
        QueryWrapper<SysOrder> queryWrapper = new QueryWrapper();
        queryWrapper.ne("state",OrderStatusEnum.DELETE.getCode());  //排除已删除的订单
        queryWrapper.ne("state",OrderStatusEnum.UNPAID.getCode());  //排除未支付的订单
//        判断角色ID
        SysUser sysUser = JwtUtil.getCurrentUser();
        if(sysUser.getRoleType() == CommonConsts.ROLETYPE_MASTER  || sysUser.getRoleType() == CommonConsts.ROLETYPE_DEALER ){
            queryWrapper.eq("buyer",sysUser.getDealerId());
        }
        if(req.getOid()!=null){
            queryWrapper.eq("oid",req.getOid());
        }
        SysOrder sysOrder = sysOrderMapper.selectOne( queryWrapper);
        SimpleDateFormat sdf = DateUtils.dayFormat.get();
        OrderInvoiceQueryInfoRes orderInvoiceQueryRes = new OrderInvoiceQueryInfoRes();
        if(sysOrder == null){
            return null;
        }
        BeanUtils.copyProperties(sysOrder,orderInvoiceQueryRes);
        Date createdAt = sysOrder.getCreatedAt();
        String format = sdf.format(createdAt);
        //查询订单细节
        List<SysOrderDetail> sysOrderDetails = sysOrderDetailMapper.findDetailAndProductInfoByOid(sysOrder.getOid());
        orderInvoiceQueryRes.setDetail(sysOrderDetails);
        log.info("sysOrderDetails==========={}",sysOrderDetails);
        log.info("req==========={}",req);
        //查询经销商
        SysDealer sysDealer = sysDealerMapper.selectByDealerId(sysOrder.getBuyer());
        if(sysDealer != null){
            SysAddr sysAddr = sysAddrMapper.selectById(sysDealer.getBillingAddrId());
            if( sysAddr != null ){
                orderInvoiceQueryRes.setBillesAddres(sysAddr);
            }
            SysAddr sysAddr2 = sysAddrMapper.selectById(sysDealer.getShopAddrId());
            if(sysAddr2 != null){
                orderInvoiceQueryRes.setShopAddres(sysAddr2);
            }
        }
        if(sysDealer != null){
            SysAddr sysAddr = sysAddrMapper.findAddrByAddrId(sysDealer.getBillingAddrId());
            if(sysAddr != null){
                orderInvoiceQueryRes.setBillesAddres(sysAddr);
            }
            SysAddr sysAddr2 = sysAddrMapper.findAddrByAddrId(sysDealer.getShopAddrId());
            if(sysAddr2 != null){
                orderInvoiceQueryRes.setShopAddres(sysAddr2);
            }
            orderInvoiceQueryRes.setBuyersName(sysDealer.getDealerName());
        }
        orderInvoiceQueryRes.setDate(format);
        // 查询卖家的购物地址
        SysDealer sysDealer2 = sysDealerMapper.selectByDealerId(sysOrder.getSellers());
        if(sysDealer2 != null){
            SysAddr sysAddr3 = sysAddrMapper.findAddrByAddrId(sysDealer2.getShopAddrId());
            SysDealerBriefVo briefVo = new SysDealerBriefVo();
            briefVo.setDealerName(sysDealer2.getDealerName());
            briefVo.setEmailAddress(sysDealer2.getEmailAddress());
            briefVo.setLogoUrl(sysDealer2.getLogoUrl());
            briefVo.setShopAddr(sysAddr3);
            orderInvoiceQueryRes.setDealerBrief(briefVo);
        }
        return orderInvoiceQueryRes;
    }

    private  List<SysDealerCollect> sysOrderCollectIncremental( String yesToday){
        //后续数据量大时 查询增量方案 查询出昨天累计记录  以下为增量方案 采用时 需注释 首次初始化
        SimpleDateFormat sdf = DateUtils.dayFormat.get();
        List<SysDealerCollect> list = sysDealerCollectMapper.genOrderCollectByTime(yesToday);
        QueryWrapper<SysDealerCollect> queryWrapper = new QueryWrapper<>();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH,-2);
        queryWrapper.eq("data_date",sdf.format(calendar.getTime()));
        List<SysDealerCollect> sysDealerCollects = sysDealerCollectMapper.selectList(queryWrapper);
        Map<Long, SysDealerCollect> collect = sysDealerCollects.stream().collect(Collectors.toMap(SysDealerCollect::getDealerId, SysDealerCollect->SysDealerCollect));
        if(list!=null&&list.size()>0){
            for(SysDealerCollect sys:list){
                sys.setCreateAt(new Date());
                SysDealerCollect sysDealerCollect = collect.get(sys.getDealerId());
                if(sysDealerCollect!=null){
                    sys.setPurchaseOrdNumAgg(sys.getPurchaseOrdNumCur()+sysDealerCollect.getPurchaseOrdNumAgg());
                    sys.setPurchaseOrdNumFinalAgg(sys.getPurchaseOrdNumFinalCur()+sysDealerCollect.getPurchaseOrdNumFinalAgg());
                    sys.setTotalSalesAgg(sys.getTotalSalesCur().add(sysDealerCollect.getTotalSalesAgg()));
                    sys.setTotalProfitAgg(sys.getTotalProfitCur().add(sysDealerCollect.getTotalProfitAgg()));
                }
            }
        }
        return list;
    }
}
